﻿using System.Collections.ObjectModel;

namespace XDCCManager.Model.Servers
{
	public class Server : BaseModel, System.ICloneable
	{
		public Server()
		{
			addresses = new ObservableCollection<ServerAddress>();
			Network = string.Empty;
			BotName = string.Empty;
			Nick = string.Empty;
			Password = string.Empty;
		}

		private string network;

		/// <summary>
		/// Network name. Informational only.
		/// </summary>
		public string Network
		{
			get { return network; }
			set { if (network != value) { network = value; OnPropertyChanged("Network"); } }
		}

		private ObservableCollection<ServerAddress> addresses;

		/// <summary>
		/// List of IRC server address to contact.
		/// </summary>
		[System.Xml.Serialization.XmlElement("Address")]
		public ObservableCollection<ServerAddress> Addresses
		{
			get { return addresses; }
		}

		private string botname;

		/// <summary>
		/// The name of the user under which an XDCC server is running.
		/// </summary>
		public string BotName
		{
			get { return botname; }
			set { if (botname != value) { botname = value; OnPropertyChanged("BotName"); } }
		}

		private string nick;

		/// <summary>
		/// The user name to connect to server with.
		/// </summary>
		public string Nick
		{
			get { return nick; }
			set { if (nick != value) { nick = value; OnPropertyChanged("Nick"); } }
		}

		private string password;

		/// <summary>
		/// The XDCC server administrative password.
		/// </summary>
		public string Password
		{
			get { return password; }
			set { if (password != value) { password = value; OnPropertyChanged("Password"); } }
		}

		private UploadServiceKind uploadServiceKind;

		public UploadServiceKind UploadServiceKind
		{
			get { return uploadServiceKind; }
			set { if (uploadServiceKind != value) { uploadServiceKind = value; OnPropertyChanged("UploadServiceKind"); } }
		}

		private UploadService uploadService;

		[System.Xml.Serialization.XmlElement("FtpUploadService", typeof(FtpUploadService))]
		public UploadService UploadService
		{
			get { return uploadService; }
			set { if (uploadService != value) { uploadService = value; OnPropertyChanged("UploadService"); } }
		}

		#region ICloneable Members

		public object Clone()
		{
			Server clone = new Server()
			{
				Network = Network,
				BotName = BotName,
				Nick = Nick,
				UploadServiceKind = UploadServiceKind,
				Password = Password
			};
			for (int i = 0; i < Addresses.Count; i++)
				clone.Addresses.Add(Addresses[i].Clone() as ServerAddress);
			if (UploadService != null)
				clone.UploadService = UploadService.Clone() as UploadService;
			return clone;
		}

		#endregion

		public override bool Equals(object obj)
		{
			if (base.Equals(obj))
				return true;
			if (!(obj is Server))
				return false;
			Server server = obj as Server;
			if ((server.Network != Network) ||
				(server.Nick != Nick) ||
				(server.BotName != BotName) ||
				(server.Addresses.Count != Addresses.Count) ||
				(server.Password != Password) ||
				(server.UploadServiceKind != UploadServiceKind) ||
				((server.UploadService == null) && (UploadService != null)) ||
				((server.UploadService != null) && (UploadService == null)) ||
				((server.UploadService != null) && (UploadService != null) && (!server.UploadService.Equals(UploadService))))
				return false;
			System.Collections.Generic.List<ServerAddress> addresses = new System.Collections.Generic.List<ServerAddress>(server.Addresses);
			foreach (var address in Addresses)
			{
				for (int i = 0; i < addresses.Count; i++)
				{
					if (addresses[i].Equals(address))
					{
						addresses.RemoveAt(i);
						break;
					}
				}
			}
			return addresses.Count == 0;
		}

		public override int GetHashCode()
		{
			return Network.GetHashCode() ^ Nick.GetHashCode() ^ BotName.GetHashCode();
		}
	}
}
